﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WiimoteLib;
using GestureLib;
using System.IO;

namespace GesturePad
{
    public partial class MainForm : Form
    {
        private delegate void RecordingFinishedDelegate();

        private GestureLib.GestureLib _gestureLib;
        private Wiimote _wiimote;

        private string _currentFileName;

        public MainForm()
        {
            InitializeComponent();
        }

        private void chkMarker_CheckedChanged(object sender, EventArgs e)
        {
            if (chkMarker.Checked)
            {
                chkMarker.Text = "AN";
            }
            else
            {
                chkMarker.Text = "AUS";
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            _gestureLib = new GestureLib.GestureLib();

            //_gestureLib.GestureDevice = CreateAndGetWiiDevice();
            _gestureLib.GestureDevice = CreateAndGetMouseDevice();

            #region Create Algorithms
            IGestureAlgorithm shakingTopBottom = new ShakingTopBottomGestureAlgorithm { Name = "Shaking: Top <-> Bottom" }; 
            IGestureAlgorithm shakingLeftRight = new ShakingLeftRightGestureAlgorithm { Name = "Shaking: Left <-> Right" }; 
            IGestureAlgorithm roll = new RollGestureAlgorithm { Name = "Roll" }; 
            IGestureAlgorithm jab = new JabGestureAlgorithm { Name = "Jab" }; 
            IGestureAlgorithm pitch = new PitchGestureAlgorithm { Name = "Pitch" }; 

            IGestureAlgorithm pointerLeftRight = new LeftRightGestureAlgorithm { Name = "Left -> Right" };
            IGestureAlgorithm pointerTopBottom = new TopBottomGestureAlgorithm { Name = "Top -> Bottom" };
            IGestureAlgorithm pointerBottomTop = new BottomTopGestureAlgorithm { Name = "Bottom -> Top" };
            IGestureAlgorithm pointerRightLeft = new RightLeftGestureAlgorithm { Name = "Right -> Left" };
            IGestureAlgorithm pointerDiagonalBottomLeftTopRight = new DiagonalBottomLeftTopRightGestureAlgorithm { Name = "Bottom-Left -> Top-Right" };
            IGestureAlgorithm pointerDiagonalTopLeftBottomRight = new DiagonalTopLeftBottomRightGestureAlgorithm { Name = "Top-Left -> Bottom-Right" };
            IGestureAlgorithm pointerDiagonalTopRightBottomLeft = new DiagonalTopRightBottomLeftGestureAlgorithm { Name = "Top-Right -> Bottom-Left" };
            IGestureAlgorithm pointerDiagonalBottomRightTopLeft = new DiagonalBottomRightTopLeftGestureAlgorithm { Name = "Bottom-Right -> Top-Left" };
            #endregion

            #region Create Actions Gestures
            WriteEditorTextAction letterA = new WriteEditorTextAction { TextBox = rtbEditor, Text = "A", Name = "Write Character A" };
            WriteEditorTextAction letterB = new WriteEditorTextAction { TextBox = rtbEditor, Text = "B", Name = "Write Character B" };
            WriteEditorTextAction letterC = new WriteEditorTextAction { TextBox = rtbEditor, Text = "C", Name = "Write Character C" };
            WriteEditorTextAction letterD = new WriteEditorTextAction { TextBox = rtbEditor, Text = "D", Name = "Write Character D" };
            WriteEditorTextAction letterE = new WriteEditorTextAction { TextBox = rtbEditor, Text = "E", Name = "Write Character E" };
            WriteEditorTextAction letterF = new WriteEditorTextAction { TextBox = rtbEditor, Text = "F", Name = "Write Character F" };
            WriteEditorTextAction letterG = new WriteEditorTextAction { TextBox = rtbEditor, Text = "G", Name = "Write Character G" };
            WriteEditorTextAction letterH = new WriteEditorTextAction { TextBox = rtbEditor, Text = "H", Name = "Write Character H" };
            WriteEditorTextAction letterI = new WriteEditorTextAction { TextBox = rtbEditor, Text = "I", Name = "Write Character I" };
            WriteEditorTextAction letterJ = new WriteEditorTextAction { TextBox = rtbEditor, Text = "J", Name = "Write Character J" };
            WriteEditorTextAction letterK = new WriteEditorTextAction { TextBox = rtbEditor, Text = "K", Name = "Write Character K" };
            WriteEditorTextAction letterL = new WriteEditorTextAction { TextBox = rtbEditor, Text = "L", Name = "Write Character L" };
            WriteEditorTextAction letterM = new WriteEditorTextAction { TextBox = rtbEditor, Text = "M", Name = "Write Character M" };
            WriteEditorTextAction letterN = new WriteEditorTextAction { TextBox = rtbEditor, Text = "N", Name = "Write Character N" };
            WriteEditorTextAction letterO = new WriteEditorTextAction { TextBox = rtbEditor, Text = "O", Name = "Write Character O" };
            WriteEditorTextAction letterP = new WriteEditorTextAction { TextBox = rtbEditor, Text = "P", Name = "Write Character P" };
            WriteEditorTextAction letterQ = new WriteEditorTextAction { TextBox = rtbEditor, Text = "Q", Name = "Write Character Q" };
            WriteEditorTextAction letterR = new WriteEditorTextAction { TextBox = rtbEditor, Text = "R", Name = "Write Character R" };
            WriteEditorTextAction letterS = new WriteEditorTextAction { TextBox = rtbEditor, Text = "S", Name = "Write Character S" };
            WriteEditorTextAction letterT = new WriteEditorTextAction { TextBox = rtbEditor, Text = "T", Name = "Write Character T" };
            WriteEditorTextAction letterU = new WriteEditorTextAction { TextBox = rtbEditor, Text = "U", Name = "Write Character U" };
            WriteEditorTextAction letterV = new WriteEditorTextAction { TextBox = rtbEditor, Text = "V", Name = "Write Character V" };
            WriteEditorTextAction letterW = new WriteEditorTextAction { TextBox = rtbEditor, Text = "W", Name = "Write Character W" };
            WriteEditorTextAction letterX = new WriteEditorTextAction { TextBox = rtbEditor, Text = "X", Name = "Write Character X" };
            WriteEditorTextAction letterY = new WriteEditorTextAction { TextBox = rtbEditor, Text = "Y", Name = "Write Character Y" };
            WriteEditorTextAction letterZ = new WriteEditorTextAction { TextBox = rtbEditor, Text = "Z", Name = "Write Character Z" };

            WriteEditorTextAction digit0 = new WriteEditorTextAction { TextBox = rtbEditor, Text = "0", Name = "Write Digit 0" };
            WriteEditorTextAction digit1 = new WriteEditorTextAction { TextBox = rtbEditor, Text = "1", Name = "Write Digit 1" };
            WriteEditorTextAction digit2 = new WriteEditorTextAction { TextBox = rtbEditor, Text = "2", Name = "Write Digit 2" };
            WriteEditorTextAction digit3 = new WriteEditorTextAction { TextBox = rtbEditor, Text = "3", Name = "Write Digit 3" };
            WriteEditorTextAction digit4 = new WriteEditorTextAction { TextBox = rtbEditor, Text = "4", Name = "Write Digit 4" };
            WriteEditorTextAction digit5 = new WriteEditorTextAction { TextBox = rtbEditor, Text = "5", Name = "Write Digit 5" };
            WriteEditorTextAction digit6 = new WriteEditorTextAction { TextBox = rtbEditor, Text = "6", Name = "Write Digit 6" };
            WriteEditorTextAction digit7 = new WriteEditorTextAction { TextBox = rtbEditor, Text = "7", Name = "Write Digit 7" };
            WriteEditorTextAction digit8 = new WriteEditorTextAction { TextBox = rtbEditor, Text = "8", Name = "Write Digit 8" };
            WriteEditorTextAction digit9 = new WriteEditorTextAction { TextBox = rtbEditor, Text = "9", Name = "Write Digit 9" };

            SwitchCaseTextAction caseToUpper = new SwitchCaseTextAction { Case = WriteEditorTextAction.LetterCase.Upper, LetterCaseChanged = LetterCaseChanged, Name = "Make Upper Case" };
            SwitchCaseTextAction caseToLower = new SwitchCaseTextAction { Case = WriteEditorTextAction.LetterCase.Lower, LetterCaseChanged = LetterCaseChanged, Name = "Make Lower Case" };

            SpecialEditorTextAction letterSpace = new SpecialEditorTextAction { TextBox = rtbEditor, Action = SpecialEditorTextAction.SpecialAction.Space, Name = "Write Space" };
            SpecialEditorTextAction letterBackSpace = new SpecialEditorTextAction { TextBox = rtbEditor, Action = SpecialEditorTextAction.SpecialAction.BackSpace, Name = "Delete Character" };

            #endregion
            
            #region Create Trained Gestures
            /*
            TrainedGesture letterAGesture = new TrainedGesture();
            letterAGesture.GestureActions.Add(letterA);
            letterAGesture.GestureAlgorithms.Add(pointerDiagonalBottomLeftTopRight);
            letterAGesture.GestureAlgorithms.Add(pointerDiagonalTopLeftBottomRight);
            letterAGesture.GestureAlgorithms.Add(pointerRightLeft);
            letterAGesture.Name = "LetterA";

            TrainedGesture letterCGesture = new TrainedGesture();
            letterCGesture.GestureActions.Add(letterC);
            letterCGesture.GestureAlgorithms.Add(pointerDiagonalTopRightBottomLeft);
            letterCGesture.GestureAlgorithms.Add(pointerDiagonalTopLeftBottomRight);
            letterCGesture.Name = "LetterC";

            TrainedGesture letterDGesture = new TrainedGesture();
            letterDGesture.GestureActions.Add(letterD);
            letterDGesture.GestureAlgorithms.Add(pointerBottomTop);
            letterDGesture.GestureAlgorithms.Add(pointerDiagonalTopLeftBottomRight);
            letterDGesture.GestureAlgorithms.Add(pointerDiagonalTopRightBottomLeft);
            letterDGesture.Name = "LetterD";

            TrainedGesture letterEGesture = new TrainedGesture();
            letterEGesture.GestureActions.Add(letterE);
            letterEGesture.GestureAlgorithms.Add(pointerRightLeft);
            letterEGesture.GestureAlgorithms.Add(pointerTopBottom);
            letterEGesture.GestureAlgorithms.Add(pointerLeftRight);
            letterEGesture.Name = "LetterE";

            TrainedGesture letterFGesture = new TrainedGesture();
            letterFGesture.GestureActions.Add(letterF);
            letterFGesture.GestureAlgorithms.Add(pointerRightLeft);
            letterFGesture.GestureAlgorithms.Add(pointerTopBottom);
            letterFGesture.Name = "LetterF";

            TrainedGesture letterGGesture = new TrainedGesture();
            letterGGesture.GestureActions.Add(letterG);
            letterGGesture.GestureAlgorithms.Add(pointerRightLeft);
            letterGGesture.GestureAlgorithms.Add(pointerTopBottom);
            letterGGesture.GestureAlgorithms.Add(pointerLeftRight);
            letterGGesture.GestureAlgorithms.Add(pointerBottomTop);
            letterGGesture.Name = "LetterG";

            TrainedGesture letterHGesture = new TrainedGesture();
            letterHGesture.GestureActions.Add(letterH);
            letterHGesture.GestureAlgorithms.Add(pointerTopBottom);
            letterHGesture.GestureAlgorithms.Add(pointerDiagonalBottomLeftTopRight);
            letterHGesture.GestureAlgorithms.Add(pointerTopBottom);
            letterHGesture.Name = "LetterH";

            TrainedGesture letterIGesture = new TrainedGesture();
            letterIGesture.GestureActions.Add(letterI);
            letterIGesture.GestureAlgorithms.Add(pointerTopBottom);
            letterIGesture.Name = "LetterI";

            TrainedGesture letterJGesture = new TrainedGesture();
            letterJGesture.GestureActions.Add(letterJ);
            letterJGesture.GestureAlgorithms.Add(pointerTopBottom);
            letterJGesture.GestureAlgorithms.Add(pointerRightLeft);
            letterJGesture.GestureAlgorithms.Add(pointerBottomTop);
            letterJGesture.Name = "LetterJ";

            TrainedGesture letterKGesture = new TrainedGesture();
            letterKGesture.GestureActions.Add(letterK);
            letterKGesture.GestureAlgorithms.Add(pointerDiagonalTopRightBottomLeft);
            letterKGesture.GestureAlgorithms.Add(pointerBottomTop);
            letterKGesture.GestureAlgorithms.Add(pointerDiagonalTopLeftBottomRight);
            letterKGesture.Name = "LetterK";

            TrainedGesture letterLGesture = new TrainedGesture();
            letterLGesture.GestureActions.Add(letterL);
            letterLGesture.GestureAlgorithms.Add(pointerTopBottom);
            letterLGesture.GestureAlgorithms.Add(pointerLeftRight);
            letterLGesture.Name = "LetterL";

            TrainedGesture letterMGesture = new TrainedGesture();
            letterMGesture.GestureActions.Add(letterM);
            letterMGesture.GestureAlgorithms.Add(pointerBottomTop);
            letterMGesture.GestureAlgorithms.Add(pointerDiagonalTopLeftBottomRight);
            letterMGesture.GestureAlgorithms.Add(pointerDiagonalBottomLeftTopRight);
            letterMGesture.GestureAlgorithms.Add(pointerTopBottom);
            letterMGesture.Name = "LetterM";

            TrainedGesture letterNGesture = new TrainedGesture();
            letterNGesture.GestureActions.Add(letterN);
            letterNGesture.GestureAlgorithms.Add(pointerBottomTop);
            letterNGesture.GestureAlgorithms.Add(pointerDiagonalTopLeftBottomRight);
            letterNGesture.GestureAlgorithms.Add(pointerBottomTop);
            letterNGesture.Name = "LetterN";

            TrainedGesture letterOGesture = new TrainedGesture();
            letterOGesture.GestureActions.Add(letterO);
            letterOGesture.GestureAlgorithms.Add(pointerRightLeft);
            letterOGesture.GestureAlgorithms.Add(pointerTopBottom);
            letterOGesture.GestureAlgorithms.Add(pointerLeftRight);
            letterOGesture.GestureAlgorithms.Add(pointerBottomTop);
            letterOGesture.Name = "LetterO";

            TrainedGesture letterPGesture = new TrainedGesture();
            letterPGesture.GestureActions.Add(letterP);
            letterPGesture.GestureAlgorithms.Add(pointerBottomTop);
            letterPGesture.GestureAlgorithms.Add(pointerLeftRight);
            letterPGesture.GestureAlgorithms.Add(pointerTopBottom);
            letterPGesture.GestureAlgorithms.Add(pointerRightLeft);
            letterPGesture.Name = "LetterP";

            TrainedGesture letterQGesture = new TrainedGesture();
            letterQGesture.GestureActions.Add(letterQ);
            letterQGesture.GestureAlgorithms.Add(pointerRightLeft);
            letterQGesture.GestureAlgorithms.Add(pointerTopBottom);
            letterQGesture.GestureAlgorithms.Add(pointerLeftRight);
            letterQGesture.GestureAlgorithms.Add(pointerBottomTop);
            letterQGesture.GestureAlgorithms.Add(pointerDiagonalTopLeftBottomRight);
            letterQGesture.Name = "LetterQ";


            TrainedGesture caseToUpperGesture = new TrainedGesture();
            caseToUpperGesture.GestureActions.Add(caseToUpper);
            caseToUpperGesture.GestureAlgorithms.Add(pointerLeftRight);
            caseToUpperGesture.GestureAlgorithms.Add(pointerBottomTop);
            caseToUpperGesture.Name = "CaseToUpper";

            TrainedGesture caseToLowerGesture = new TrainedGesture();
            caseToLowerGesture.GestureActions.Add(caseToLower);
            caseToLowerGesture.GestureAlgorithms.Add(pointerLeftRight);
            caseToLowerGesture.GestureAlgorithms.Add(pointerTopBottom);
            caseToLowerGesture.Name = "CaseToLower";

            TrainedGesture letterSpaceGesture = new TrainedGesture();
            letterSpaceGesture.GestureActions.Add(letterSpace);
            letterSpaceGesture.GestureAlgorithms.Add(pointerLeftRight);
            letterSpaceGesture.Name = "LetterSpace";

            TrainedGesture letterBackSpaceGesture = new TrainedGesture();
            letterBackSpaceGesture.GestureActions.Add(letterBackSpace);
            letterBackSpaceGesture.GestureAlgorithms.Add(pointerRightLeft);
            letterBackSpaceGesture.Name = "LetterBackSpace";
            */
            #endregion

            #region Register GestureLib stuff
            //Register Algorithms
            _gestureLib.AvailableGestureAlgorithms.Add(shakingTopBottom);
            _gestureLib.AvailableGestureAlgorithms.Add(shakingLeftRight);
            _gestureLib.AvailableGestureAlgorithms.Add(roll);
            _gestureLib.AvailableGestureAlgorithms.Add(jab);
            _gestureLib.AvailableGestureAlgorithms.Add(pitch);

            _gestureLib.AvailableGestureAlgorithms.Add(pointerLeftRight);
            _gestureLib.AvailableGestureAlgorithms.Add(pointerRightLeft);
            _gestureLib.AvailableGestureAlgorithms.Add(pointerTopBottom);
            _gestureLib.AvailableGestureAlgorithms.Add(pointerBottomTop);
            _gestureLib.AvailableGestureAlgorithms.Add(pointerDiagonalBottomLeftTopRight);
            _gestureLib.AvailableGestureAlgorithms.Add(pointerDiagonalBottomRightTopLeft);
            _gestureLib.AvailableGestureAlgorithms.Add(pointerDiagonalTopLeftBottomRight);
            _gestureLib.AvailableGestureAlgorithms.Add(pointerDiagonalTopRightBottomLeft);
            
            //Register Actions
            _gestureLib.AvailableGestureActions.Add(letterA);
            _gestureLib.AvailableGestureActions.Add(letterB);
            _gestureLib.AvailableGestureActions.Add(letterC);
            _gestureLib.AvailableGestureActions.Add(letterD);
            _gestureLib.AvailableGestureActions.Add(letterE);
            _gestureLib.AvailableGestureActions.Add(letterF);
            _gestureLib.AvailableGestureActions.Add(letterG);
            _gestureLib.AvailableGestureActions.Add(letterH);
            _gestureLib.AvailableGestureActions.Add(letterI);
            _gestureLib.AvailableGestureActions.Add(letterJ);
            _gestureLib.AvailableGestureActions.Add(letterK);
            _gestureLib.AvailableGestureActions.Add(letterL);
            _gestureLib.AvailableGestureActions.Add(letterM);
            _gestureLib.AvailableGestureActions.Add(letterN);
            _gestureLib.AvailableGestureActions.Add(letterO);
            _gestureLib.AvailableGestureActions.Add(letterP);
            _gestureLib.AvailableGestureActions.Add(letterQ);
            _gestureLib.AvailableGestureActions.Add(letterR);
            _gestureLib.AvailableGestureActions.Add(letterS);
            _gestureLib.AvailableGestureActions.Add(letterT);
            _gestureLib.AvailableGestureActions.Add(letterU);
            _gestureLib.AvailableGestureActions.Add(letterV);
            _gestureLib.AvailableGestureActions.Add(letterW);
            _gestureLib.AvailableGestureActions.Add(letterX);
            _gestureLib.AvailableGestureActions.Add(letterY);
            _gestureLib.AvailableGestureActions.Add(letterZ);

            _gestureLib.AvailableGestureActions.Add(digit0);
            _gestureLib.AvailableGestureActions.Add(digit1);
            _gestureLib.AvailableGestureActions.Add(digit2);
            _gestureLib.AvailableGestureActions.Add(digit3);
            _gestureLib.AvailableGestureActions.Add(digit4);
            _gestureLib.AvailableGestureActions.Add(digit5);
            _gestureLib.AvailableGestureActions.Add(digit6);
            _gestureLib.AvailableGestureActions.Add(digit7);
            _gestureLib.AvailableGestureActions.Add(digit8);
            _gestureLib.AvailableGestureActions.Add(digit9);

            _gestureLib.AvailableGestureActions.Add(caseToLower);
            _gestureLib.AvailableGestureActions.Add(caseToUpper);
            _gestureLib.AvailableGestureActions.Add(letterSpace);
            _gestureLib.AvailableGestureActions.Add(letterBackSpace);
            /*
            //Register Trained Gestures
            _gestureLib.TrainedGestures.Add(letterAGesture);
            //_gestureLib.TrainedGestures.Add(letterBGesture);
            _gestureLib.TrainedGestures.Add(letterCGesture);
            _gestureLib.TrainedGestures.Add(letterDGesture);
            _gestureLib.TrainedGestures.Add(letterEGesture);
            _gestureLib.TrainedGestures.Add(letterFGesture);
            _gestureLib.TrainedGestures.Add(letterGGesture);
            _gestureLib.TrainedGestures.Add(letterHGesture);
            _gestureLib.TrainedGestures.Add(letterIGesture);
            _gestureLib.TrainedGestures.Add(letterJGesture);
            _gestureLib.TrainedGestures.Add(letterKGesture);
            _gestureLib.TrainedGestures.Add(letterLGesture);
            _gestureLib.TrainedGestures.Add(letterMGesture);
            _gestureLib.TrainedGestures.Add(letterNGesture);
            _gestureLib.TrainedGestures.Add(letterOGesture);
            _gestureLib.TrainedGestures.Add(letterPGesture);
            _gestureLib.TrainedGestures.Add(letterQGesture);

            _gestureLib.TrainedGestures.Add(caseToUpperGesture);
            _gestureLib.TrainedGestures.Add(caseToLowerGesture);
            _gestureLib.TrainedGestures.Add(letterSpaceGesture);
            _gestureLib.TrainedGestures.Add(letterBackSpaceGesture);
            */
            #endregion

            _gestureLib.Recording.RecordingFinished += new EventHandler(Recording_RecordingFinished);

            _gestureLib.Recording.ShowOverlayWhenBeginRecording = true;
            _gestureLib.ScreenBounds = Screen.PrimaryScreen.Bounds;
            _gestureLib.ImpersonatingMouse = true;

            //Create the ConfigurationManager and set the important properties
            XmlConfigurationManager xmlConfigurationManager = new XmlConfigurationManager();
            xmlConfigurationManager.FileName = Path.Combine(Application.StartupPath, "TrainedGestures.xml");
            
            //Assign the XmlConfigurationManger to the GestureLib
            _gestureLib.ConfigurationManager = xmlConfigurationManager;

            //Load the saved TrainedGesture-Objects
            _gestureLib.ConfigurationManager.Load();
        }

        private void LetterCaseChanged(WriteEditorTextAction.LetterCase letterCase)
        {
            WriteEditorTextAction.Case = letterCase;

            switch (letterCase)
            {
                case WriteEditorTextAction.LetterCase.Upper:
                    lblLetterCaseState.Text = "ABC";
                    break;
                case WriteEditorTextAction.LetterCase.Lower:
                    lblLetterCaseState.Text = "abc";
                    break;
                default:
                    lblLetterCaseState.Text = "Unknown";
                    break;
            }
        }

        private void RecordingFinished()
        {
            if (InvokeRequired)
            {
                RecordingFinishedDelegate dlg = new RecordingFinishedDelegate(RecordingFinished);
                this.Invoke(dlg);
            }
            else
            {
                //Bug occures: when every character was deleted, zoom factor is automatically set to 1.0F
                float savedZoomFactor = rtbEditor.ZoomFactor;

                GestureAlgorithmCollection gestures = _gestureLib.Recording.RecognizeRecording(_gestureLib.Recording.RecordedAccelerationGestureStates);
                TrainedGesture matchedTrainedGesture = _gestureLib.TrainedGestures.GetTrainedGestureByMatchedAlgorithms(gestures);

                if (matchedTrainedGesture != null)
                {
                    matchedTrainedGesture.GestureActions.ExecuteAll();
                }

                //TODO: Doppelten Code rausschmeißen
                PointTendenceAnalyzer pointTendenceAnalyzer = _gestureLib.Recording.RecognizeRecording(_gestureLib.Recording.RecordedPointerGestureStates);
                matchedTrainedGesture = _gestureLib.TrainedGestures.GetTrainedGestureByMatchedAlgorithms(pointTendenceAnalyzer.MatchedGestureAlgorithms);

                foreach (IGestureAlgorithm alg in pointTendenceAnalyzer.MatchedGestureAlgorithms)
                {
                    System.Diagnostics.Debug.WriteLine(alg.GetType().FullName);
                }

                if (matchedTrainedGesture != null)
                {
                    matchedTrainedGesture.GestureActions.ExecuteAll();
                }

                rtbEditor.ZoomFactor = savedZoomFactor;
            }
        }

        private void Recording_RecordingFinished(object sender, EventArgs e)
        {
            RecordingFinished();
        }

        private WiiGestureDevice CreateAndGetWiiDevice()
        {
            _wiimote = new Wiimote();
            _wiimote.Connect();
            _wiimote.SetReportType(Wiimote.InputReport.IRAccel, true);
            _wiimote.SetLEDs(false, true, true, false);

            //attach create WiiGestureDevice to GestureLib
            WiiGestureDevice wiiDevice = new WiiGestureDevice();
            wiiDevice.Dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher;
            wiiDevice.Wiimote = _wiimote;            

            return wiiDevice;
        }

        private MouseGestureDevice CreateAndGetMouseDevice()
        {
            MouseGestureDevice mouseGestureDevice = new MouseGestureDevice(Screen.PrimaryScreen.Bounds.Size, true);
            mouseGestureDevice.MatchingMouseButton = MouseGestureDevice.MouseButton.RightButton;

            return mouseGestureDevice;
        }

        private void btnZoomIn_Click(object sender, EventArgs e)
        {
            rtbEditor.ZoomFactor += 0.2F;
        }

        private void btnZoomOut_Click(object sender, EventArgs e)
        {
            rtbEditor.ZoomFactor -= 0.2F;
        }

        private void btnResetZoom_Click(object sender, EventArgs e)
        {
            rtbEditor.ZoomFactor = 4.0F;
        }

        private void rtbEditor_SelectionChanged(object sender, EventArgs e)
        {
            if (rtbEditor.SelectionLength > 0 && chkMarker.Checked)
            {
                if (rtbEditor.SelectionBackColor == Color.Yellow)
                    rtbEditor.SelectionBackColor = Color.Transparent;
                else
                    rtbEditor.SelectionBackColor = Color.Yellow;

                //rtbEditor.SelectionStart = rtbEditor.SelectionStart + rtbEditor.SelectionLength;
            }
        }

        private void btnConfigureTrainedGestures_Click(object sender, EventArgs e)
        {
            TrainedGesturesConfigurationForm trainedGesturesConfigurationForm = new TrainedGesturesConfigurationForm();

            trainedGesturesConfigurationForm.GestureLib = _gestureLib;
            trainedGesturesConfigurationForm.ShowDialog();

            _gestureLib.ConfigurationManager.Save();
        }

        private void btnScrollDown_Click(object sender, EventArgs e)
        {
            ScrollTextArea(rtbEditor.Height);
        }

        private void btnScrollUp_Click(object sender, EventArgs e)
        {
            ScrollTextArea(-rtbEditor.Height);
        }

        void ScrollTextArea(int pixels)
        {
            ScrollerApi scrollerApi = new ScrollerApi(rtbEditor.Handle);
            scrollerApi.Scroll(pixels);

            rtbEditor.Focus();

            //rtbEditor.ScrollBars = RichTextBoxScrollBars.None;
        }

        private void btnNew_Click(object sender, EventArgs e)
        {
            rtbEditor.Text = string.Empty;
            _currentFileName = null;
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            if (ofdTextFile.ShowDialog() == DialogResult.OK)
            {
                _currentFileName = ofdTextFile.FileName;

                StreamReader reader = new StreamReader(_currentFileName);
                rtbEditor.Text = reader.ReadToEnd();
                reader.Close();
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            bool saveFile = false;

            if (_currentFileName == null)
            {
                if (sfdTextFile.ShowDialog() == DialogResult.OK)
                {
                    _currentFileName = sfdTextFile.FileName;
                    saveFile = true;
                }
            }
            else
            {
                saveFile = true;
            }

            if (saveFile)
            {
                StreamWriter writer = new StreamWriter(_currentFileName);
                writer.Write(rtbEditor.Text);
                writer.Close();            
            }
        } 
    }
}
